/*
 * Copyright (c) 2013, FPX and/or its affiliates. All rights reserved.
 * Use, Copy is subject to authorized license.
 */
package pyip.lib.javaweb;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;

import org.apache.commons.lang3.StringUtils;

import pyip.lib.mixtool.util.JacksonUtil;

import com.fasterxml.jackson.core.JsonProcessingException;

/**
 * 公共工具类
 * @author shiw
 *         2014年12月2日
 */
public class CommonUtil {

    /** hibernate校验器 */
    private static javax.validation.Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    /**
     * 将异常堆栈转换为字符串
     * @param aThrowable 异常
     * @return String
     */
    public static String getStackTrace(Throwable aThrowable) {
        final Writer result = new StringWriter();
        final PrintWriter printWriter = new PrintWriter(result);
        aThrowable.printStackTrace(printWriter);
        return result.toString();
    }

    /**
     * 获取用户ip地址
     * @date 2013-8-1
     * @param
     * @return
     */
    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * 输出json数据
     * @param response
     * @param obj
     * @throws Exception
     */
    public static void writeJson(HttpServletResponse response, Object obj) throws Exception {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String json = JacksonUtil.toJson(obj);
        out.write(json);
        out.flush();
        out.close();
    }

    /**
     * 获取UTF8字符长度，英文字符为1，中文及其他为3
     * @param value
     * @return
     */
    public static int getUtf8Length(String value) {
        if (StringUtils.isBlank(value)) {
            return 0;
        }
        return value.getBytes().length;
    }

    /**
     * 校验对象的属性
     * @param object 校验的对象
     * @param request
     * @return
     */
    public static List<Validator> validate(Object object, HttpServletRequest request) {
        List<Validator> validatorList = new ArrayList<Validator>();
        Set<ConstraintViolation<Object>> set = validator.validate(object);
        for (ConstraintViolation<Object> v : set) {
            Validator validator = new Validator();
            validator.setName(v.getPropertyPath().toString());
            String value = null;
            if (v.getInvalidValue() != null) {
                value = v.getInvalidValue().toString();
            }
            validator.setValue(value);
            validator.setMsg(BaseController.getText(request, v.getMessage(), replaceArgs(v)));
            validatorList.add(validator);
        }
        return validatorList;
    }

    /**
     * 替换占位符
     * @param v
     * @return
     */
    private static Object[] replaceArgs(ConstraintViolation<Object> v) {
        Map<String, Object> map = v.getConstraintDescriptor().getAttributes();
        if (map.containsKey("value")) {
            return new Object[] { map.get("value").toString() };
        }
        if (map.containsKey("max")) {
            return new Object[] { map.get("max").toString() };
        }
        if (map.containsKey("min") && map.containsKey("max")) {
            return new Object[] { map.get("min").toString(), map.get("max").toString() };
        }
        return null;
    }

    /**
     * 将request的参数反转成参数对象
     * @param request
     * @param param
     * @return
     * @throws JsonProcessingException
     * @throws Exception
     */
    public static Object getRequestObject(HttpServletRequest request, Class<?> clazz) {
        Enumeration<String> names = request.getParameterNames();
        Map<String, Object> map = new HashMap<String, Object>();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            String[] values = request.getParameterValues(name);
            if (values.length > 1) {
                map.put(name, values);
            } else {
                map.put(name, values[0]);
            }
        }
        String json = JacksonUtil.toJson(map);
        return JacksonUtil.fromJson(json, clazz);
    }
}
